use std::{alloc::{GlobalAlloc, Layout}, ptr::{null, null_mut}};
use crate::{constants::{MI_PADDING_SIZE, MI_SMALL_SIZE_MAX}, internal::{_mi_heap_get_free_small_page, _mi_is_power_of_two}, prim::mi_prim_get_default_heap, types::MiHeap};



pub struct RustMimalloc;

unsafe impl GlobalAlloc for RustMimalloc {
    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
        mi_heap_malloc_aligned(mi_prim_get_default_heap(), layout)
    }

    unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
        unimplemented!()
        
    }

    unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
        unimplemented!()
    }
}

unsafe fn mi_heap_malloc_aligned(heap: *mut MiHeap, layout: Layout) -> *mut u8 {
    mi_heap_malloc_aligned_at(heap, layout, 0)
}

unsafe fn mi_heap_malloc_aligned_at(heap: *mut MiHeap, layout: Layout, offset: usize) -> *mut u8 {
    mi_heap_malloc_zero_aligned_at(heap, layout, offset, false)
}

unsafe fn mi_heap_malloc_zero_aligned_at(heap: *mut MiHeap, layout: Layout, offset: usize, zero: bool) -> *mut u8 {
    let size = layout.size();
    let alignment = layout.align();
    if alignment == 0 || !_mi_is_power_of_two(alignment) {
        eprintln!("aligned allocation requires the alignment to be a power-of-two (size {}, alignment {})", size, alignment);
        return null_mut::<u8>();
    }
    // try first if there happens to be a small block available with just the right alignment

    if size <= MI_SMALL_SIZE_MAX && alignment <= size {
        let align_mask: usize = alignment - 1;
        let padsize = size + MI_PADDING_SIZE;
        let page = _mi_heap_get_free_small_page(heap, padsize);
        if !(*page).free.is_null() {
            let is_aligned = ((((*page).free as usize) + offset) & align_mask) == 0;
            if is_aligned {
                // MI_STAT = 0
            }
        }
    }

    null_mut::<u8>()
}

